package hbasecli.binary.controller;

import hbasecli.binary.model.StringResponse;
import hbasecli.exception.HBaseDataAccessException;
import hbasecli.exception.ParamException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

@RestControllerAdvice(basePackages = {"hbasecli.binary.controller"})
public class BinaryExceptionHandlers {

    private static final Logger log = LoggerFactory.getLogger(BinaryExceptionHandlers.class);

    @ExceptionHandler(value = {
            MissingServletRequestParameterException.class,
            MethodArgumentTypeMismatchException.class,
            HttpMessageNotReadableException.class
    })
    public ResponseEntity<byte[]> handleHttpException(Exception exception) {
        String detail;
        if(exception instanceof MissingServletRequestParameterException) {
            detail = exception.getMessage();
        } else if (exception instanceof MethodArgumentTypeMismatchException) {
            detail = "URL 路径参数类型不匹配";
        } else if (exception instanceof HttpMessageNotReadableException) {
            detail = "请求体中的数据格式不匹配";
        } else {
            detail = "其它请求错误";
        }
        log.error("HTTP 请求异常: ", exception);
        StringResponse stringResponse = StringResponse.newBuilder()
                .setCode(2)
                .setMessage("请求格式错误, " + detail)
                .setData("")
                .build();
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(stringResponse.toByteArray(), httpHeaders, HttpStatus.OK);
    }

    @ExceptionHandler(value = {ParamException.class})
    public ResponseEntity<byte[]> handleParamException(ParamException exception) {
        log.error("参数校验异常: ", exception);
        StringResponse stringResponse = StringResponse.newBuilder()
                .setCode(3)
                .setMessage(exception.getMsg())
                .setData("")
                .build();
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(stringResponse.toByteArray(), httpHeaders, HttpStatus.OK);
    }

    @ExceptionHandler(value = {HBaseDataAccessException.class})
    public ResponseEntity<byte[]> handleHBaseDataAccessException(HBaseDataAccessException exception) {
        log.error("HBase 数据访问异常: ", exception);
        StringResponse stringResponse = StringResponse.newBuilder()
                .setCode(4)
                .setMessage(exception.getMsg())
                .setData("")
                .build();
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(stringResponse.toByteArray(), httpHeaders, HttpStatus.OK);
    }

    @ExceptionHandler(value = {RuntimeException.class})
    public ResponseEntity<byte[]> handleRuntimeException(RuntimeException exception) {
        log.error("运行时异常: ", exception);
        StringResponse stringResponse = StringResponse.newBuilder()
                .setCode(5)
                .setMessage(exception.getMessage())
                .setData("")
                .build();
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(stringResponse.toByteArray(), httpHeaders, HttpStatus.OK);
    }

}
